#include "PeopleData.h"
#include "ZStream.h"
#include "Utilities.h"
#include "RandomSystem.h"

// RoleSkills

void RoleSkills::CalculateBestRole()
{
	if(m_skills[Goalkeeper] >= m_skills[Defender])
	{
		if(m_skills[Goalkeeper] >= m_skills[Attacker])
			m_bestRole = Goalkeeper;
		else
			m_bestRole = Attacker;
	}
	else
	{
		if(m_skills[Defender] >= m_skills[Attacker])
			m_bestRole = Defender;
		else
			m_bestRole = Attacker;
	}
}

int RoleSkills::GetAverageSkills() const 
{
	return (m_skills[Goalkeeper] + m_skills[Defender] + m_skills[Attacker]) / 3;
}

void RoleSkills::Serialize(ZStream& o_stream) const
{
	o_stream.WriteOpenTag("RoleSkills");
	o_stream.WriteAttribute("goalkeeping",	m_skills[Goalkeeper]);
	o_stream.WriteAttribute("defense",		m_skills[Defender]);
	o_stream.WriteAttribute("attack",		m_skills[Attacker]);
	o_stream.WriteAttribute("bestRole",		m_bestRole);
	o_stream.WriteCloseTag("RoleSkills");
}

void RoleSkills::Deserialize(ZStream& i_stream)
{
	i_stream.SkipLine();
	i_stream.ReadAttribute(m_skills[Goalkeeper]);
	i_stream.ReadAttribute(m_skills[Defender]);
	i_stream.ReadAttribute(m_skills[Attacker]);
	i_stream.ReadAttribute(m_bestRole);
	i_stream.SkipLine();
}

void RoleSkills::SetRole(const int i_role)
{
	assert(i_role >= 0 && i_role < NUM_SKILL_ROLES);
	
	m_bestRole = i_role;
	
	if(i_role == Goalkeeper)
		STL::swap(Utilities::Max3(m_skills[Goalkeeper], m_skills[Defender], m_skills[Attacker]), m_skills[Goalkeeper]);
	else if(i_role == Defender)
		STL::swap(Utilities::Max3(m_skills[Goalkeeper], m_skills[Defender], m_skills[Attacker]), m_skills[Defender]);
	else
		STL::swap(Utilities::Max3(m_skills[Goalkeeper], m_skills[Defender], m_skills[Attacker]), m_skills[Attacker]);
}

// PeopleSkills

void PeopleSkills::Serialize(ZStream& o_stream) const
{
	o_stream.WriteOpenTag("PeopleSkills");
	
	o_stream.WriteOpenTag("PeopleSkills");
	m_playerSkills.Serialize(o_stream);
	o_stream.WriteCloseTag("PeopleSkills");

	o_stream.WriteOpenTag("MaxPlayerSkills");
	m_maxPlayerSkills.Serialize(o_stream);
	o_stream.WriteCloseTag("MaxPlayerSkills");

	o_stream.WriteOpenTag("TrainerSkills");
	m_trainerSkills.Serialize(o_stream);
	o_stream.WriteCloseTag("TrainerSkills");

	o_stream.WriteOpenTag("MentalSkills");
	o_stream.WriteAttribute("charisma",		m_mentalSkills[Charisma]);
	o_stream.WriteAttribute("intelligence",	m_mentalSkills[Intelligence]);
	o_stream.WriteAttribute("aggressivity",	m_mentalSkills[Aggressivity]);
	o_stream.WriteCloseTag("MentalSkills");

	o_stream.WriteOpenTag("PhysicsSkills");
	o_stream.WriteAttribute("resistance",	m_physicsSkills[Resistance]);
	o_stream.WriteAttribute("stamina",	m_physicsSkills[Stamina]);
	o_stream.WriteAttribute("fatigue",		m_physicsSkills[Fatigue]);
	o_stream.WriteCloseTag("PhysicsSkills");

	o_stream.WriteCloseTag("PeopleSkills");
}

void PeopleSkills::Deserialize(ZStream& i_stream)
{
	i_stream.SkipLine();

	i_stream.SkipLine();
	m_playerSkills.Deserialize(i_stream);
	i_stream.SkipLine();

	i_stream.SkipLine();
	m_maxPlayerSkills.Deserialize(i_stream);
	i_stream.SkipLine();

	i_stream.SkipLine();
	m_trainerSkills.Deserialize(i_stream);
	i_stream.SkipLine();

	i_stream.SkipLine();
	i_stream.ReadAttribute(m_mentalSkills[Charisma]);
	i_stream.ReadAttribute(m_mentalSkills[Intelligence]);
	i_stream.ReadAttribute(m_mentalSkills[Aggressivity]);
	i_stream.SkipLine();

	i_stream.SkipLine();
	i_stream.ReadAttribute(m_physicsSkills[Resistance]);
	i_stream.ReadAttribute(m_physicsSkills[Stamina]);
	i_stream.ReadAttribute(m_physicsSkills[Fatigue]);
	i_stream.SkipLine();

	i_stream.SkipLine();
}

void PeopleSkills::Generate(const bool i_isPlayer)
{
	for(int i=0; i<NUM_MEN_SKILLS; ++i)
		m_mentalSkills[i] = RandIntBetween(1, 99);

	for(int i=0; i<NUM_SKILL_ROLES; ++i)
	{
		m_playerSkills[i] = RandIntBetween(1, 120);
		m_trainerSkills[i] = RandIntBetween(1, 9);
	}

	m_physicsSkills[Resistance] = RandIntBetween(1, 120);

	STL::swap(Utilities::Max4(m_playerSkills[Goalkeeper], m_playerSkills[Defender], m_playerSkills[Attacker], m_physicsSkills[Resistance]), m_physicsSkills[Resistance]);
	const int diceRoll = Rand()%100;
	m_playerSkills.SetRole( diceRoll >= 60 ? Attacker : (diceRoll >= 20 ? Defender : Goalkeeper) );

	if(!i_isPlayer)
	{
		STL::swap(m_playerSkills, m_trainerSkills);
		m_physicsSkills[Resistance] = RandIntBetween(1, 9);
	}

	for(int i=0; i<NUM_SKILL_ROLES; ++i)
	{
		m_maxPlayerSkills[i] = m_playerSkills[i];
	}

	m_physicsSkills[Fatigue] = 0;
	m_physicsSkills[Stamina] = m_physicsSkills[Resistance];
}

// PlayerAvailability
void PlayerAvailability::Serialize(ZStream& o_stream) const
{
	o_stream.WriteOpenTag("Discipline");
	o_stream.WriteAttribute("DaysExpulsion", m_daysExpulsion);
	o_stream.WriteAttribute("DaysBroken", m_daysBroken);
	o_stream.WriteCloseTag("Discipline");
}

void PlayerAvailability::Deserialize(ZStream& i_stream)
{
	i_stream.SkipLine();
	i_stream.ReadAttribute(m_daysExpulsion);
	i_stream.ReadAttribute(m_daysBroken);
	i_stream.SkipLine();
}

void PlayerAvailability::Clear()
{
	m_daysExpulsion = 0;
	m_daysBroken = 0;
}
